package com.yirui.bridge.udp;

import com.yirui.bridge.udp.parser.Item0cParser;
import com.yirui.bridge.udp.parser.Item0dParser;
import com.yirui.bridge.udp.parser.Item79;
import com.yirui.bridge.udp.parser.Item79Parser;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Dujie
 * @create 2021/11/24
 * @since 1.0.0
 */
@Slf4j
public class UdpChannelInboundHandler extends SimpleChannelInboundHandler<DatagramPacket> {
    private NettyUdpClient nettyUdpClient;
    private static Map<Integer, DataParser> parsers = new java.util.concurrent.ConcurrentHashMap<>();
    static {
        parsers.put(0x0c, new Item0cParser());
        parsers.put(0x79, new Item79Parser());
        parsers.put(0x0d, new Item0dParser());
    }

    public UdpChannelInboundHandler(NettyUdpClient nettyUdpClient) {
        this.nettyUdpClient = nettyUdpClient;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket) throws Exception {

        nettyUdpClient.getReceiveData().set(true);

        ByteBuf buffer = datagramPacket.content();

        log.debug("收到UDP服务应答包:{}", datagramPacket.content().toString(CharsetUtil.UTF_8));//new String(ByteBufUtil.getBytes(buf)));
        parseDAMData(buffer);
    }


    //DAM中控
    /*
    输入：
通道3：
  增加0.5Db：A5AC0C001100320000020253
           引导码   处理器类型ID 处理器编号            Item   V0  V1  V2  V3   开始通道     结束通道   校验码
  返回：A5 AC   0C                 00               11     00  32  00  01   02          02            54   (12)
  减少0.5Db：A5AC0C0011FFCE00000202EE
  返回：A5 AC   0C                 00               11     FF  CE  00  01   02          02            EF   (12)

设备操作返回说明：
该操作为同步操作，即发送一条命令后马上返回应答消息。
对于设置\查询，如果成功，按照此协议返回且V3=1。
如果失败，按照此协议返回且V3=0。
    * */


    private void parseDAMData(ByteBuf buffer) {
        int len = buffer.readableBytes();
        if( len == 12){
            byte type = buffer.getByte(2);
            int itemIndex = buffer.getByte(4);
            int number = buffer.getByte(3);
            String key = String.format("%02x_%02x", type, number);

            DataParser parser = parsers.get(type&0xff);
            if(parser == null) {
                log.debug("当前数据包未实现解析处理程序");
                return ;
            }
            if(parser.isSingleValue()){
                Object res =  parser.parse(buffer, itemIndex, null);
                nettyUdpClient.getRes().put(key, res);
            }else {
                Object c = nettyUdpClient.getRes().get(key);
                Map container = null;
                if (c == null) {
                    container = new HashMap();
                    nettyUdpClient.getRes().put(key, container);
                } else {
                    container = (HashMap) c;
                }
                parser.parse(buffer, itemIndex, container);

            }

        }
    }

}
